
#include <testpackage.h>
#include "package.h"
#include "judge_file.h"
#include <string.h>
#include <stdlib.h>

jstatus_t __stdcall judge_file_open(struct judge_fs *fs, /* out */ struct judge_file **file, const char *path) {
	struct zip_file *z;
	struct package *package = (struct package *)fs;

	z = zip_fopen(package->zip, path, ZIP_FL_NOCASE);
	if (z == NULL)
		return JSTATUS_ZIP_ERROR;	
	*file = (struct judge_file *)malloc(sizeof(struct judge_file));
	if (*file == NULL)
		return JSTATUS_BAD_ALLOC;
	(*file)->zip = z;
	return JSTATUS_SUCCESS;
}

void __stdcall judge_file_close(struct judge_fs *fs, struct judge_file *file) {
	if (file->zip != NULL)
		zip_fclose(file->zip);
	file->zip = NULL;
	free(file);
}

jstatus_t __stdcall judge_file_read(struct judge_fs *fs, struct judge_file *file, char *buffer, uint32_t size, /* out */ uint32_t *actual_size) {
	size_t sz = zip_fread(file->zip, buffer, size);

	if (actual_size != NULL) 
		*actual_size = sz;
	return JSTATUS_SUCCESS;
}

jstatus_t __stdcall judge_file_find(struct judge_fs *fs, /* out */ const char **path, const char *prefix, /* in out */ void **context) {
	struct package *package = (struct package *)fs;
	int32_t num_entries, i, length_prefix, length_name;
	const char *name;
	
	num_entries = zip_get_num_entries(package->zip, 0);
	length_prefix = strlen(prefix);
	for (i = *(int32_t *)context; i < num_entries; i += 1) {
		name = zip_get_name(package->zip, i, 0);
		length_name = strlen(name);
		if (length_name < length_prefix) 
			continue;
		if (strncmp(prefix, name, length_prefix) == 0 && name[length_name - 1] != '/') {
			*(int32_t *)context = i + 1;
			*path = name;
			return JSTATUS_SUCCESS;
		}
	}
	*path = NULL;
	return JSTATUS_FILE_NOT_FOUND;
}
